/*
 * CSInstaller.cs
 * 
 * Microsoft Office SharePoint Server Managed Protocol Handler
 * 
 * Author: John Kozell (johnkoz@microsoft.com)
 *         Microsoft Coroporation
 * 
 * This code is an adaptation from, and interpretation of, the original SPS 2001 SDK
 * and has been updated with available information at the time of writing.
 * Not all the delcarions and alogrithms have been verified and tested
 * and there is no guarantee that they are accurate or valid, now or in the future.
 * 
 * The .NET Managed COM Interop approach contained herin was NOT created in cooperation
 * with the Microsoft SharePoint product group and has not been officially endorced
 * by Microsoft and therefore is not supported. The user of this code assumes any
 * and all risk with its use and should proceed with discression.
 * 
 * THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 */

using System;

using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search.Administration;

namespace CSInstaller
{

	/// <summary>
	/// Summary description for CInstaller.
	/// </summary>
	class CSInstaller
	{
		private static string displayName = "Custom Content Source";
		private static string url;
		private static string sourceGroup;
		private static int hops;
		private static int depth;
		private static bool followComplexUrls;
		private static string userName;
		private static string password;
		private static string siteName;
		private static string serverName;
		private static string index;
		private static string action;

		[STAThread]
		static void Main(string[] args)
		{
			try
			{
				SetArgs(args);	
				switch (action)
				{
					case "INSTALL":
						Install();
						break;
					case "UNINSTALL":
                        Uninstall();
						break;
					case "LIST":
						ListCatalogs();
						break;
					default:
						Usage();
						break;
				}
				Console.WriteLine("Press Enter to exit.");
				Console.ReadLine();
			}
			catch
			{
				Usage();
			}
		}

		static void SetArgs(string[] args)
		{
			foreach(string arg in args)
			{
				bool first=true;
				try
				{
					if(first)
					{
						first=false;
						switch(arg.ToLower())
						{
							case "/i":
								action = "INSTALL";
								break;
							case "/u":
								action = "UNINSTALL";
								break;
							case "/l":
								action = "LIST";
								break;
						}
					}
					string argval = arg.Substring(arg.IndexOf(":")+1);
					switch(arg.Substring(1,arg.IndexOf(":")-1))
					{
						case "displayName":
							displayName = argval;
							break;
						case "serverName":
							serverName = argval;
							break;
						case "siteName":
							siteName = argval;
							break;
						case "index":
							index = argval;
							break;
						case "url":
							url=argval;
							break;
						case "sourceGroup":
							sourceGroup=argval;
							break;
						case "hops":
							hops = int.Parse(argval);
							break;
						case "depth":
							depth= int.Parse(argval);
							break;
						case "followComplexUrls":
							followComplexUrls = (argval=="T");
							break;
						case "userName":
							userName = argval;
							break;
						case "password":
							password = argval;
							break;


						default:
							Console.WriteLine("** not using " + arg);
							break;
					}
				}
				catch
				{}
			}
		}

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// Test command line:
        ///     /l /siteName:http://johnkoz-labmoss
        /// </remarks>
        static void ListCatalogs()
		{
			try
			{
                using (SPSite site = new SPSite(siteName))
                {
                    SearchContext searchContext = SearchContext.GetContext(site);
                    Content content = new Content(searchContext);
                    Console.WriteLine("Search Context:" + searchContext.Name);
                    foreach (ContentSource contentSource in content.ContentSources)
                    {
                        Console.WriteLine(string.Format("\tContent Source: {0}, Tag: {1}, Start Addresses:", contentSource.Name, contentSource.Tag));
                        foreach (Uri startAddress in contentSource.StartAddresses)
                        {
                            Console.WriteLine(string.Format("\t\tAddress: {0}, ", startAddress.ToString()));
                        }
                    }
                }
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
		}

		static void Usage()
		{
			
			Console.WriteLine("== Usage ==");

			Console.WriteLine(" List indexes (catalogs): ");
			Console.WriteLine("	CSInstaller /L ");
			Console.WriteLine("		/serverName:<server>");
			Console.WriteLine("		/siteName:<site> ");
			Console.WriteLine(" Remove Content Source: ");
			Console.WriteLine("	CSInstaller /U ");
			Console.WriteLine("		/serverName:<server>");
			Console.WriteLine("		/siteName:<site> ");
			Console.WriteLine("		/url:<proto://server/path>");
			Console.WriteLine(" Add Content Source: ");
			Console.WriteLine("	CSInstaller /I" );
			Console.WriteLine("		/serverName:<server> ");
			Console.WriteLine("		/siteName:<http://server[:port]/[.../]> ");
			Console.WriteLine("		/index:<indexname>");
			Console.WriteLine("		/url:<proto://server/path>");
			Console.WriteLine("		/sourceGroup:<group> ");
			Console.WriteLine("		/hops:<#> ");
			Console.WriteLine("		/depth:<#> ");
			Console.WriteLine("		/followComplexUrls:[T | F]");
			Console.WriteLine("		[/displayName:<name>]" );
			Console.WriteLine("		[/userName:<name>]" );
			Console.WriteLine("		[/password:<password>]");
		}
		static void Uninstall()
		{
			try
			{
                //SearchSite ss = new SearchSite();
                //ss.Connect(serverName,siteName);
                //SearchCatalog sc = ss.GetCatalog(index);
                //sc.RemoveContentSource(url);
                //Console.WriteLine("Content source removed.");
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex);
			}
		}

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// Test command line:
        ///     /i /siteName:http://johnkoz-labmoss /url:MOSSPH://johnkoz-labmoss /displayName:"My Content Source"
        /// </remarks>
        static void Install()
		{
			try
			{
                using (SPSite site = new SPSite(siteName))
                {
                    SearchContext searchContext = SearchContext.GetContext(site);
                    Content content = new Content(searchContext);

                    CustomContentSource contentSource = (CustomContentSource)content.ContentSources.Create(typeof(CustomContentSource), displayName);
                    if (contentSource != null)
                    {
                        contentSource.StartAddresses.Add(new Uri(url));
                        contentSource.FollowDirectories = true;
                        contentSource.Update();
                        Console.WriteLine("Content source added.");

                        //SearchSite ss = new SearchSite();
                        //ss.Connect(serverName,siteName);

                        //SearchCatalog sc = ss.GetCatalog(index);

                        //SearchContentSource contentSource = sc.AddContentSource(url,sourceGroup,hops,depth,followComplexUrls,userName,password);
                        //if (contentSource != null)
                        //{
                        //    if (displayName != null)
                        //        contentSource.DisplayName = displayName;
                        //    contentSource.FollowDirectories = true;
                        //    Console.WriteLine("Content source added.");
                        //}
                    }
                }
			}
			catch (Exception ex)
			{
				Console.WriteLine("Error: " + ex.ToString());
				
			}
		}
	}
}
